#include <algorithm>
#include "Projectile.hpp"

std::string						Projectile::_filename = "../images/projectile.png";
std::shared_ptr<ALLEGRO_BITMAP>	Projectile::_image;

std::list<Projectile> Projectile::all_projectiles;

Projectile::Projectile(const Vector& position, const Vector& direction, const float velocity)
	: _position(position),
	  _forward(VecNormalize(direction)),
	  _velocity(velocity)
{
	bool image_loaded(_image);
	if(!image_loaded)
		_image.reset(al_load_bitmap(_filename.c_str()), [](ALLEGRO_BITMAP* p){al_destroy_bitmap(p);});

	all_projectiles.push_back(*this);
}

Vector Projectile::GetPosition() const
{
	return _position;
}

void Projectile::Update(float dt)
{
	_position += _forward * _velocity * dt;
}

/**
 *	Assumptions are made about window size in this function.
 */
void Projectile::UpdateAllProjectiles(float dt)
{
	auto projectile_it = all_projectiles.begin();
	while(projectile_it != all_projectiles.end())
	{
		projectile_it->Update(dt);

		// Remove the projectile if it's outside of the bounds of the window.
		bool out_of_bounds
			= (projectile_it->_position.x <= 0 || 512 <= projectile_it->_position.x) || (projectile_it->_position.y <= 0 || 512 <= projectile_it->_position.y);
		if(out_of_bounds)
		{
			projectile_it = all_projectiles.erase(projectile_it);
			continue;
		}

		++projectile_it;
	}
}

void Projectile::Draw() const
{
	// Note: I'm using the rotated version of this call because it allows me to
	// center the image.
	al_draw_rotated_bitmap(_image.get(), 8, 8, _position.x, _position.y, 0, 0);
}

void Projectile::DrawAllProjectiles()
{
	std::for_each(all_projectiles.begin(), all_projectiles.end(), 
		[](const Projectile& p)
	{
		p.Draw();
	});
}

/**
 *	This function came to be from laziness. A better solution would be a class
 *	that manages the lifetime of projecties. Don't use this in the actual game.
 */
void Projectile::CleanUpProjectiles()
{
	all_projectiles.clear();
	_image.reset();
}